package cooperated

import (
	"fmt"
	"sort"

	"gddgame.cc/galaxy/common/namespaces/cooperate"
	"gddgame.cc/galaxy/common/namespaces/cooperate/structure"
	"gddgame.cc/galaxy/project/breeder/breeder/model"
	"gddgame.cc/galaxy/utils"
	"gddgame.cc/galaxy/utils/serialize"
)

func (logic *TypeMap) Custom(info *structure.ScheduleInfo, content *cooperate.CustomScheduleContent) {
	slot := serialize.GetSlot()
	switch content.Type {
	case BatchUpdateCustomType:
		// 运行攻击
		var batchUpdate BatchUpdateCustomLogic
		if err := slot.Set(&batchUpdate); err != nil {
			fmt.Println("touch attack", err)
		} else if err := slot.Unmarshal(content.Logic); err != nil {
			fmt.Println("touch attack", err)
		} else {
			logic.BatchUpdate(info, &batchUpdate)
		}
	case BatchOperateCustomType:
		var batchOperate BatchOperateCustomLogic
		if err := slot.Set(&batchOperate); err != nil {
			fmt.Println("touch attack", err)
		} else if err := slot.Unmarshal(content.Logic); err != nil {
			fmt.Println("touch attack", err)
		} else {
			logic.BatchOperate(info, &batchOperate)
		}
	}
	slot.Release()
}

func (logic *TypeMap) BatchUpdate(info *structure.ScheduleInfo, batchUpdate *BatchUpdateCustomLogic) {
	for _, id := range batchUpdate.Ids {
		baseData := structure.NewBaseData(batchUpdate.DataType, id)
		//fmt.Println("batch update", baseData)
		info := logic.GetDetailCache(logic, baseData)
		if info == nil {
			return
		}
		fd := logic.GetFieldsDefine(batchUpdate.DataType)
		for index, tt := range batchUpdate.TargetDepends {
			keys := batchUpdate.TargetKeys[index]
			beIndex, ok := fd.BeDependMap[tt]
			if !ok {
				continue
			}
			if keys != nil {
				sort.StringsAreSorted(keys)
			} else {
				keys = []string{}
			}
			beDepend := fd.BeDepends[beIndex]
			ii := info.ListDepend(beDepend)
			if ii == nil {
				continue
			}
			for _, iid := range ii {
				bbaseData := structure.NewBaseData(beDepend.DependType, iid)
				iinfo := logic.GetDetailCache(logic, bbaseData)
				if len(keys) > 0 {
					kk := iinfo.ToString(Key)
					i := sort.SearchStrings(keys, kk)
					if i < 0 || keys[i] != kk {
						continue
					}
				}
				logic.Update(utils.ToInt(id), byte(beDepend.DependType), iid, batchUpdate.Scene)
			}
		}
	}
}

func (logic *TypeMap) BatchOperate(info *structure.ScheduleInfo, batchOperate *BatchOperateCustomLogic) {
	fd := logic.GetFieldsDefine(batchOperate.DataType)
	for id := range batchOperate.Ids {
		baseData := structure.NewBaseData(batchOperate.DataType, id)
		info := logic.GetDetailCache(logic, baseData)
		key := batchOperate.TargetKey
		for _, beDepend := range fd.BeDepends {
			if beDepend.DependType != batchOperate.TargetType {
				continue
			}
			ii := info.ListDepend(beDepend)
			for _, iid := range ii {
				bbaseData := structure.NewBaseData(beDepend.DependType, iid)
				iinfo := logic.GetDetailCache(logic, bbaseData)
				if key != "" {
					kk := iinfo.ToString(Key)
					if key != kk {
						continue
					}
				}
				// 提交buff信息
				updateData := cooperate.OperateContent{
					MapNoId: logic.GetMapNoId(),
					Target:  bbaseData,
					Operates: []cooperate.OperateData{
						cooperate.NewOperateData(cooperate.BatchUpdateOperate, &cooperate.UpdateOperateData{
							Data:     *bbaseData,
							Operates: batchOperate.Operates,
						}),
					},
				}
				logic.PushOperate(updateData, 0)
			}
		}
	}
}

func (logic *TypeMap) CustomTouch(info *structure.ScheduleInfo, content *cooperate.TouchScheduleContent) {
	switch info.Target.DataType {
	case ItemType:
		logic.CustomItemTouch(info, content)
	}
}

func (logic *TypeMap) CustomItemTouch(info *structure.ScheduleInfo, content *cooperate.TouchScheduleContent) {
	instance := logic.GetDetailCache(logic, info.Target)
	fmt.Println("custom", info.Target, instance.ToString(Key), content)
	key := instance.ToString(Key)
	itemId := logic.Center.TargetIdMap[ItemType][key]
	item := logic.Center.ItemMap[itemId]
	position := instance.ToBytes(Position)
	if item.Receive != nil {
		if info.Params == nil || len(info.Params) < 2 {
			return
		}
		targetInfo := logic.GetDetailCache(logic, structure.NewBaseData(structure.PublicDataType(utils.ToByte(info.Params[0])), info.Params[1]))

		owner := logic.GetAbilityInstance(logic, instance)
		effect := owner.Generate(logic, instance, logic)
		// 删除
		destroy := &DestroyTask{
			DataType: instance.GetDataType(),
			Id:       instance.GetId(),
			Identity: instance.ToInt(Identity),
			Key:      key,
			Position: position,
			Ability: &Ability{
				Level:         1,
				DirectAbility: effect.GetIds(model.DirectAbilityDefine),
				BuffAbility:   effect.GetIds(model.BuffAbilityDefine),
				AttrAbility:   effect.GetSlice(model.AttrAbilityDefine),
			},
		}
		builder := logic.TaskBuilder()
		if info.From != nil {
			builder.From(structure.NewBaseDataFrom(info.From))
		}
		builder.BindMapNoId(logic.GetMapNoId()).One(DestroyTaskEvent, destroy).Task(0, nil)

		//拾取到账号
		accountId := targetInfo.ToInt(AccountDataType)
		logic.Center.OnReceiveNotice(logic, accountId, item)
	}
}
